package com.nbwyctf.helper.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.nbwyctf.helper.annotation.Authenticate;
import com.nbwyctf.helper.exception.BusinessException;
import com.nbwyctf.helper.pojo.User;
import com.nbwyctf.helper.service.AuthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chetaifu
 */
public class LoginInterceptor implements HandlerInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    /** 自定义cookie名 */
    private final String COOKIE_NAME = "COOKIE";

    /** 拦截之前调用（进入Controller之前）*/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("request in, 验证用户身份中...");
        //如果不是映射到方法，直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String requestUrl = request.getRequestURI();
        // 拦截url开头为api的资源
        if (!requestUrl.startsWith("/api")) {
            return true;
        }  else if (method.isAnnotationPresent(Authenticate.class) && !checkLogin(request)) {
            // 如果没有登录
            // 可以选择抛出指定异常
            // throw new BusinessException(LOGIN_AUTH_ERROR);
            response.setContentType("application/json; charset=utf-8");
            response.setStatus(401);
            PrintWriter writer = response.getWriter();
            Map<String, Object> result = new HashMap<>(1);
            result.put("msg", "尚未登录");
            writer.print(OBJECT_MAPPER.writeValueAsString(result));
            response.flushBuffer();
            return false;
        } else {
            return true;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}

    private boolean checkLogin(HttpServletRequest request) throws IOException{
        //根据请求数据，找到cookie数组
        Cookie[] cookies = request.getCookies();
        //获取一下session
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            // if (user == null){}
            // 如果没有从session中读取到保存的用户信息
            String cookieValue = null;
            if (cookies != null) {
                for (int i = 0; i < cookies.length; i++) {
                    if (cookies[i].getName().equals(COOKIE_NAME)) {
                        cookieValue = cookies[i].getValue();
                        break;
                    }
                }
            }

            logger.info("当前系统session内不存在用户信息，获取到的 COOKIE_NAME 是：{}", cookieValue);
            if (cookieValue != null) {
                Map<String, Object> params = new HashMap<>(1);
                params.put(COOKIE_NAME, cookieValue);

                String email = AuthService.verifierIdToken(cookieValue);
                if (Strings.isNullOrEmpty(email)) {
                    logger.debug("cookie 信息错误");
                    return false;
                }

//                User userInfo = userMapper.selectByEmail(email);
//                if (userInfo != null){
//                    session.setAttribute("user", userInfo);
//                    return true;
//                }
                logger.info("cookie 认证成功");
                return false;
            }else {
                // 尚未登录
                return false;
            }
        }
        return true;
    }
}
